home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 7 / Example 7.4 / app.cpp next >
Encoding:
C/C++ Source or Header  |  2006-08-01  |  8.4 KB  |  314 lines

  1. //////////////////////////////////////////////////////////////
  2. // Example 7.4: Placing a Weapon in the hand                //
  3. // Written by: C. Granberg, 2006                            //
  4. //////////////////////////////////////////////////////////////
  5.  
  6. #include <windows.h>
  7. #include <d3dx9.h>
  8. #include "debug.h"
  9. #include "skinnedMesh.h"
  10. #include "shader.h"
  11. #include "mesh.h"
  12.  
  13. class APPLICATION
  14. {
  15.     public:
  16.         APPLICATION();
  17.         HRESULT Init(HINSTANCE hInstance, int width, int height, bool windowed);
  18.         HRESULT Update(float deltaTime);
  19.         HRESULT Render();
  20.         HRESULT Cleanup();
  21.         HRESULT Quit();
  22.         DWORD FtoDword(float f){return *((DWORD*)&f);}
  23.  
  24.     private:
  25.         IDirect3DDevice9* m_pDevice; 
  26.         SKINNEDMESH m_skinnedMesh;
  27.         BONE *m_pHand;
  28.         MESH m_weapons[4];
  29.         int m_activeWeapon;
  30.  
  31.         float m_angle, m_time;
  32.         D3DXVECTOR3 m_handOffset;
  33.         std::vector<std::string> m_animations;
  34.         int m_activeAnimation;
  35.         D3DLIGHT9 m_light;
  36.         HWND m_mainWindow;
  37.         ID3DXFont *m_pFont;
  38.  
  39.         //Shaders
  40.         SHADER m_unitVS, m_unitPS;
  41.         D3DXHANDLE m_worldHandle, m_viewProjHandle, m_sunHandle;
  42. };
  43.  
  44. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  45. {
  46.     APPLICATION app;
  47.  
  48.     if(FAILED(app.Init(hInstance, 800, 600, true)))
  49.         return 0;
  50.  
  51.     MSG msg;
  52.     memset(&msg, 0, sizeof(MSG));
  53.     int startTime = timeGetTime(); 
  54.  
  55.     while(msg.message != WM_QUIT)
  56.     {
  57.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  58.         {
  59.             ::TranslateMessage(&msg);
  60.             ::DispatchMessage(&msg);
  61.         }
  62.         else
  63.         {    
  64.             int t = timeGetTime();
  65.             float deltaTime = (t - startTime)*0.001f;
  66.  
  67.             app.Update(deltaTime);
  68.             app.Render();
  69.  
  70.             startTime = t;
  71.         }
  72.     }
  73.  
  74.     app.Cleanup();
  75.  
  76.     return msg.wParam;
  77. }
  78.  
  79. APPLICATION::APPLICATION()
  80. {
  81.     m_pDevice = NULL; 
  82.     m_mainWindow = 0;
  83.     srand(GetTickCount());
  84.     m_angle = m_time = 0.0f;
  85. }
  86.  
  87. HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed)
  88. {
  89.     debug.Print("Application initiated");
  90.  
  91.     //Create Window Class
  92.     WNDCLASS wc;
  93.     memset(&wc, 0, sizeof(WNDCLASS));
  94.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  95.     wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
  96.     wc.hInstance     = hInstance;
  97.     wc.lpszClassName = "D3DWND";
  98.  
  99.     //Register Class and Create new Window
  100.     RegisterClass(&wc);
  101.     m_mainWindow = CreateWindow("D3DWND", "Example 7.4: Placing a Weapon in the hand", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 
  102.     SetCursor(NULL);
  103.     ShowWindow(m_mainWindow, SW_SHOW);
  104.     UpdateWindow(m_mainWindow);
  105.  
  106.     //Create IDirect3D9 Interface
  107.     IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  108.  
  109.     if(d3d9 == NULL)
  110.     {
  111.         debug.Print("Direct3DCreate9() - FAILED");
  112.         return E_FAIL;
  113.     }
  114.  
  115.     //Check that the Device supports what we need from it
  116.     D3DCAPS9 caps;
  117.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
  118.  
  119.     //Hardware Vertex Processing or not?
  120.     int vp = 0;
  121.     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  122.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  123.     else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  124.  
  125.     //Check vertex & pixelshader versions
  126.     if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
  127.     {
  128.         debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");
  129.     }
  130.  
  131.     //Set D3DPRESENT_PARAMETERS
  132.     D3DPRESENT_PARAMETERS d3dpp;
  133.     d3dpp.BackBufferWidth            = width;
  134.     d3dpp.BackBufferHeight           = height;
  135.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
  136.     d3dpp.BackBufferCount            = 1;
  137.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
  138.     d3dpp.MultiSampleQuality         = 0;
  139.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
  140.     d3dpp.hDeviceWindow              = m_mainWindow;
  141.     d3dpp.Windowed                   = windowed;
  142.     d3dpp.EnableAutoDepthStencil     = true; 
  143.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
  144.     d3dpp.Flags                      = 0;
  145.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  146.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
  147.  
  148.     //Create the IDirect3DDevice9
  149.     if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,
  150.                                  vp, &d3dpp, &m_pDevice)))
  151.     {
  152.         debug.Print("Failed to create IDirect3DDevice9");
  153.         return E_FAIL;
  154.     }
  155.  
  156.     //Release IDirect3D9 interface
  157.     d3d9->Release();
  158.  
  159.     D3DXCreateFont(m_pDevice, 18, 0, 0, 1, false,  
  160.                    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
  161.                    DEFAULT_PITCH | FF_DONTCARE, "Arial", &m_pFont);
  162.  
  163.     // Create m_light
  164.     ::ZeroMemory(&m_light, sizeof(m_light));
  165.     m_light.Type      = D3DLIGHT_DIRECTIONAL;
  166.     m_light.Ambient   = D3DXCOLOR(0.5, 0.5, 0.5, 1.0f);
  167.     m_light.Diffuse   = D3DXCOLOR(0.9, 0.9, 0.9, 1.0f);
  168.     m_light.Specular  = D3DXCOLOR(0.5, 0.5, 0.5, 1.0f);
  169.     m_light.Direction = D3DXVECTOR3(0.0f, -1.0f, 0.0f);
  170.     m_pDevice->SetLight(0, &m_light);
  171.     m_pDevice->LightEnable(0, true);
  172.  
  173.     //Load m_weapons
  174.     m_activeWeapon = 0;
  175.     m_weapons[0].Load("mesh/club.x", m_pDevice);
  176.     m_weapons[1].Load("mesh/sword.x", m_pDevice);
  177.     m_weapons[2].Load("mesh/axe.x", m_pDevice);
  178.     m_weapons[3].Load("mesh/flowers.x", m_pDevice);
  179.  
  180.     //Skinned mesh
  181.     m_skinnedMesh.Load("mesh/drone.x", m_pDevice);    
  182.     m_animations = m_skinnedMesh.GetAnimations();
  183.     m_activeAnimation = m_animations.size() - 3;
  184.     m_skinnedMesh.SetAnimation((char*)m_animations[m_activeAnimation].c_str());
  185.  
  186.     //Find left hand bone
  187.     m_pHand = m_skinnedMesh.FindBone("Bone19");
  188.     m_handOffset = D3DXVECTOR3(0.5f, 0.0f, -0.07f);
  189.  
  190.     //Set sampler state
  191.     for(int i=0;i<8;i++)
  192.     {
  193.         m_pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  194.         m_pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  195.         m_pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  196.     }
  197.  
  198.     //Setup shaders
  199.     m_unitVS.Init(m_pDevice, "shaders/lighting.vs", VERTEX_SHADER);
  200.     m_worldHandle = m_unitVS.GetConstant("matW");
  201.     m_viewProjHandle = m_unitVS.GetConstant("matVP");
  202.     m_sunHandle = m_unitVS.GetConstant("DirToSun");
  203.  
  204.     m_unitPS.Init(m_pDevice, "shaders/unit.ps", PIXEL_SHADER);
  205.  
  206.     return S_OK;
  207. }
  208.  
  209. HRESULT APPLICATION::Update(float deltaTime)
  210. {    
  211.     m_angle += deltaTime * 0.5f;
  212.     if(m_angle > D3DX_PI * 2.0f)
  213.         m_angle -= D3DX_PI * 2.0f;
  214.  
  215.     m_time = deltaTime * 0.5f;
  216.         
  217.     if(KEYDOWN(VK_SPACE))
  218.     {
  219.         m_activeWeapon++;
  220.         if(m_activeWeapon >= 4)m_activeWeapon = 0;
  221.         Sleep(300);
  222.     }
  223.     else if(KEYDOWN(VK_ESCAPE))
  224.     {
  225.         Quit();
  226.     }
  227.  
  228.     return S_OK;
  229. }    
  230.  
  231. HRESULT APPLICATION::Render()
  232. {
  233.     // Clear the viewport
  234.     m_pDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0L );
  235.  
  236.     //Set camera
  237.     D3DXMATRIX view, proj, world;
  238.     D3DXMatrixLookAtLH(&view, &D3DXVECTOR3(0.0f, 10.0f, -50.0f), &D3DXVECTOR3(0.0f, 4.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
  239.     D3DXMatrixOrthoLH(&proj, 10.0f, 9.0f, 0.1f, 1000.0f);
  240.     
  241.     //Set Skeleton to rotate around the Y-axis
  242.     D3DXMATRIX r, s;
  243.     D3DXMatrixRotationYawPitchRoll(&r, m_angle, 0.0f, 0.0f);
  244.     D3DXMatrixScaling(&s, 1.2f, 1.2f, 1.2f);
  245.     world = s * r;
  246.     
  247.     m_pDevice->SetTransform(D3DTS_VIEW, &view);
  248.     m_pDevice->SetTransform(D3DTS_PROJECTION, &proj);
  249.     m_pDevice->SetTransform(D3DTS_WORLD, &world);
  250.  
  251.     // Begin the scene 
  252.     if(SUCCEEDED(m_pDevice->BeginScene()))
  253.     {
  254.         m_unitVS.SetMatrix(m_worldHandle, world);
  255.         m_unitVS.SetMatrix(m_viewProjHandle, view * proj);
  256.  
  257.         D3DXVECTOR3 sun;
  258.         D3DXVec3Normalize(&sun, &D3DXVECTOR3(0.5f, 1.0f, -0.2));
  259.         m_unitVS.SetVector3(m_sunHandle, sun);
  260.  
  261.         m_unitVS.Begin();
  262.         m_unitPS.Begin();
  263.  
  264.         m_skinnedMesh.SetPose(world, NULL, m_time);
  265.         m_skinnedMesh.Render(NULL);
  266.  
  267.         m_unitPS.End();
  268.         m_unitVS.End();
  269.  
  270.         //Render weapon
  271.         if(m_pHand != NULL)
  272.         {
  273.             D3DXMATRIX boneMatrix = m_pHand->CombinedTransformationMatrix;
  274.             D3DXMATRIX offset, weaponTransform;
  275.             D3DXMatrixTranslation(&offset, m_handOffset.x, m_handOffset.y, m_handOffset.z);
  276.  
  277.             weaponTransform = offset * boneMatrix * world;
  278.             
  279.             m_pDevice->SetTransform(D3DTS_WORLD, &weaponTransform);
  280.             m_pDevice->SetRenderState(D3DRS_LIGHTING, true);
  281.             m_weapons[m_activeWeapon].Render();
  282.         }
  283.  
  284.         RECT r = {10, 10, 0, 0};
  285.         m_pFont->DrawText(NULL, "Space: Change Weapon", -1, &r, DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);
  286.  
  287.         // End the scene.
  288.         m_pDevice->EndScene();
  289.         m_pDevice->Present(0, 0, 0, 0);
  290.     }
  291.  
  292.     return S_OK;
  293. }
  294.  
  295. HRESULT APPLICATION::Cleanup()
  296. {
  297.     try
  298.     {
  299.         m_pFont->Release();
  300.         m_pDevice->Release();
  301.  
  302.         debug.Print("Application terminated");
  303.     }
  304.     catch(...){}
  305.  
  306.     return S_OK;
  307. }
  308.  
  309. HRESULT APPLICATION::Quit()
  310. {
  311.     ::DestroyWindow(m_mainWindow);
  312.     ::PostQuitMessage(0);
  313.     return S_OK;
  314. }